package my.design.state;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zp
 * @version 1.0
 * @description: 状态处理类
 * 一、什么是状态模式
 * 状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。
 * 二、状态模式应用场景
 * 1一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
 * 2、操作中含有庞大的多分支的条件语句，且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。 通常,有多个操作包含这一相同的条件结构。
 *      State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象，
 *      这一对象可以不依赖于其他对象而独立变化。
 * 三、状态模式与策略模式区别
 * 1、状态模式重点在各状态之间的切换从而做不同的事情，而策略模式更侧重于根据具体情况选择策略，并不涉及切换。
 * 2、状态模式不同状态下做的事情不同，而策略模式做的都是同一件事，例如聚合支付平台，有支付宝、微信支付、银联支付，虽然策略不同，但最终做的事情都是支付，
 *      也就是说他们之间是可替换的。反观状态模式，各个状态的同一方法做的是不同的事，不能互相替换。
 * 状态模式封装了对象的状态，而策略模式封装算法或策略。因为状态是跟对象密切相关的，它不能被重用；而通过从Context中分离出策略或算法，我们可以重用它们。
 * 在状态模式中，每个状态通过持有Context的引用，来实现状态转移；但是每个策略都不持有Context的引用，它们只是被Context使用。
 * 排序算法 快速排序 选择排序 冒泡排序 策略
 * 只要是和状态相关 订单、交易、支付状态。
 * 优点：
 * 1、状态模式的主要优点在于封装了转换规则，并枚举可能的状态，它将所有与某个状态有关的行为放到一个类中，并且可以方便地增加新的状态，
 *      只需要改变对象状态即可改变对象的行为，还可以让多个环境对象共享一个状态对象，从而减少系统中对象的个数；
 * 缺点：
 * 其缺点在于使用状态模式会增加系统类和对象的个数，且状态模式的结构与实现都较为复杂，
 *      如果使用不当将导致程序结构和代码的混乱，对于可以切换状态的状态模式不满足“开闭原则”的要求
 * @date 2022/10/30 17:03
 */
public class StateHandler {
    private final Map<Enum<Status>, State> stateMap = new ConcurrentHashMap<>();
    private ActivityService activityService = new ActivityService();

    public StateHandler() {
        stateMap.put(Status.Check, new CheckState(activityService)); // 待审核
        stateMap.put(Status.Close, new CloseState(activityService)); // 已关闭
        stateMap.put(Status.Doing, new DoingState(activityService)); // 活动中
        stateMap.put(Status.Editing, new EditingState(activityService)); // 编辑中
        stateMap.put(Status.Open, new OpenState(activityService)); // 已开启
        stateMap.put(Status.Pass, new PassState(activityService)); // 审核通过
        stateMap.put(Status.Refuse, new RefuseState(activityService)); // 审核拒绝
    }

    public ActivityService getActivityService() {
        return activityService;
    }

    public void setActivityService(ActivityService activityService) {
        this.activityService = activityService;
    }

    public Result arraignment() {
        return stateMap.get(activityService.getActivityInfo().getStatus()).arraignment(activityService.getActivityInfo().getStatus());
    }

    public Result checkPass() {
        return stateMap.get(activityService.getActivityInfo().getStatus()).checkPass(activityService.getActivityInfo().getStatus());
    }

    public Result checkRefuse() {
        return stateMap.get(activityService.getActivityInfo().getStatus()).checkRefuse(activityService.getActivityInfo().getStatus());
    }

    public Result checkRevoke() {
        return stateMap.get(activityService.getActivityInfo().getStatus()).checkRevoke(activityService.getActivityInfo().getStatus());
    }

    public Result close() {
        return stateMap.get(activityService.getActivityInfo().getStatus()).close(activityService.getActivityInfo().getStatus());
    }

    public Result open() {
        return stateMap.get(activityService.getActivityInfo().getStatus()).open(activityService.getActivityInfo().getStatus());
    }

    public Result doing() {
        return stateMap.get(activityService.getActivityInfo().getStatus()).doing(activityService.getActivityInfo().getStatus());
    }
}
